<template>
  <div class="clearfix">
    <a-upload :file-list="fileList" @change="handleChange" @remove="handleRemove">
      <a-button>
        <upload-outlined></upload-outlined>
        Select File
      </a-button>
    </a-upload>
    {{ chunkList }} == {{ fileSuffix }}==={{ fileMd5 }}
    <a-progress type="circle" :percent="successfulChunkPercents" />
  </div>
</template>
<script setup>
import md5 from 'js-md5';
import {getBaseURL} from "~/config/common.js";

const fileList = ref([]); // 分片列表
const currentFile = ref(null); // 当前选中的文件
const chunkSize = ref(32 * 1024 * 1024); // 分片大小
const chunkCount = ref(0); // 分片数量
const chunksUploaded = ref(0); // 已上传的分片数量
const fileMd5 = ref(''); // 文件的md5值
const fileSuffix = ref(''); // 文件后缀
const successfulChunkPercents = ref(0); // 上传成功的分片百分比
const chunkList = ref([]); // 分片列表
const uploading = ref(false);
const result = ref({})
const handleRemove = file => {
  const index = fileList.value.indexOf(file);
  const newFileList = fileList.value.slice();
  newFileList.splice(index, 1);
  fileList.value = newFileList;
};

const handleChange = (info) => {
  const file = info.file;
  const reader = new FileReader()
  reader.readAsArrayBuffer(file.originFileObj);
  reader.onload = (event) => {
    const fileContent = event.target.result
    fileMd5.value = md5(fileContent).toString()
    currentFile.value = file.originFileObj;
    chunkCount.value = Math.ceil(file.size / chunkSize.value);
    chunksUploaded.value = 0;
    fileSuffix.value = "." + file.name.split('.').pop()
    successfulChunkPercents.value = 0
    for (let i = 0; i < chunkCount.value; i++) {
      const start = i * chunkSize.value;
      const end = Math.min(start + chunkSize.value - 1, currentFile.value.size - 1);
      chunkList.value[i] = currentFile.value.slice(start, end)
    }

    handleUpload()
  };
  reader.onerror = (error) => {
    console.error('读取文件时发生错误:', error);
  };


};

const handleUpload = async () => {
  const res = await useHttpGet(getBaseURL() + `/minio/checkExits?md5=${fileMd5.value}&fileSuffix=${fileSuffix.value}`)
  if (res.data) {
    successfulChunkPercents.value = 100
    alert('文件上传成功')
    return
  }
  const chunkPromises = [];
  for (let i = 0; i < chunkList.value.length; i++) {
    chunkPromises.push(uploadChunk(chunkList.value[i], i + 1, () => {
      successfulChunkPercents.value += 99 / chunkCount.value
      chunksUploaded.value++
    }))
  }
  // 等待所有分片上传完成
  await Promise.all(chunkPromises);

  if (chunksUploaded.value === chunkCount.value) {
    const mergeResult = await useHttpPost(getBaseURL() + `/minio/merge?md5=${fileMd5.value}&fileSuffix=${fileSuffix.value}&chunkTotal=${chunkCount.value}`)
    if (mergeResult.data.startsWith("[miss_chunk]")) {
      alert('文件缺失，请重新上传')
      return
    }
    successfulChunkPercents.value = 100
    alert(mergeResult.data)
  }
}

const uploadChunk = async (chunk, chunkIndex, onSuccess) => {
  let retryTime = 5;
  try {
    const formData = new FormData()
    formData.append('md5', fileMd5.value)
    formData.append('chunkIndex', chunkIndex);
    formData.append('chunk', chunk);
    const resp = await useHttpUpload( '/minio/uploadfile', {body: formData})
    onSuccess(resp)
  }catch (e){
    if (retryTime > 0) {
      retryTime--;
      return uploadChunk(chunk, chunkIndex, onSuccess);
    }
  }
}
</script>

